﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.IO;
using Google.GData.Client;
using Google.GData.Extensions;
using Google.GData.Spreadsheets;

namespace WriteBankTransactionRecordsToGoogleSpreadsheet
{
	class Program
	{
		static void Main(string[] args)
		{
			#region precheck
			if (args.Length == 0)
			{
				Assembly a = Assembly.GetExecutingAssembly();
				Stream strHelp = a.GetManifestResourceStream(typeof(Program).Namespace + ".Help.txt");
				using (StreamReader sr = new StreamReader(strHelp))
				{
					Console.Write(sr.ReadToEnd());
				}
				Environment.Exit(0);
			} 
			#endregion

			Dictionary<string, string> argDic = Global.Global.convertArgs(args);

			SpreadsheetsService service = createSpreadsheetsService(argDic["a"], argDic["p"]);

			SpreadsheetQuery query = new SpreadsheetQuery();
			Console.Write("Finding spreadsheet");
			SpreadsheetFeed spreadsheetFeed = null;

			spreadsheetFeed = service.Query(query);

			foreach (SpreadsheetEntry spreadsheetEntry in spreadsheetFeed.Entries)
			{
				Console.Write(".");
				if (spreadsheetEntry.Title.Text == argDic["d"])
				{
					Console.WriteLine("found");

					#region process the spreadsheet
					AtomLink link = spreadsheetEntry.Links.FindService(GDataSpreadsheetsNameTable.WorksheetRel, null);

					WorksheetQuery worksheetQuery = new WorksheetQuery(link.HRef.ToString());
					WorksheetFeed worksheetFeed = service.Query(worksheetQuery);

					foreach (WorksheetEntry worksheetEntry in worksheetFeed.Entries)
					{
						Console.WriteLine(worksheetEntry.Title.Text);
						if (worksheetEntry.Title.Text == "main")
						{

							Dictionary<int, object> existedRecordsetHashTable = new Dictionary<int, object>();

							#region process the worksheet
							AtomLink listFeedLink = worksheetEntry.Links.FindService(GDataSpreadsheetsNameTable.ListRel, null);
							ListQuery listQuery = new ListQuery(listFeedLink.HRef.ToString());
							ListFeed listFeed = service.Query(listQuery);

							foreach (ListEntry worksheetRow in listFeed.Entries)
							{
								ListEntry.CustomElementCollection cells = worksheetRow.Elements;

								string[] cellsData = new string[cells.Count];
								for (int i = cellsData.Length - 1;i>=0 ; i--)
								{
									if (cells[i].LocalName == "hash")
									{
										existedRecordsetHashTable.Add(Int32.Parse(cells[i].Value),null);
										break;
									}
								}
							}

							#endregion

							#region process the input txt file
							using (StreamReader sr = new StreamReader(argDic["s"],Encoding.GetEncoding("big5")))
							{
								while (!sr.EndOfStream)
								{
									string lineData=sr.ReadLine();
									string[]cells=lineData.Split('\t');
									int currentLineHash = getHash(cells);

									if (!existedRecordsetHashTable.ContainsKey(currentLineHash))
									{
										#region add into worksheet
										Console.WriteLine("writing..." + lineData); 
										
										ListEntry newRow = new ListEntry();

										int i = 0;
										foreach (string cell in cells)
										{
											ListEntry.Custom curElement = new ListEntry.Custom();
											curElement.LocalName = ((ListEntry)listFeed.Entries[0]).Elements[i] .LocalName;
											if (i == 0)
											{
												curElement.Value = toWestDate( cell.Trim());
											}
											else
											{
												curElement.Value = cell.Trim();
											}

											newRow.Elements.Add(curElement);

											i++;
										}

										ListEntry.Custom hashCell=new ListEntry.Custom();
										hashCell.LocalName="hash";
										hashCell.Value = currentLineHash.ToString();
										newRow.Elements.Add(hashCell);

										listFeed.Insert(newRow);

										#endregion
									}
								}
							}
							#endregion

							break;
						}
					}


					#endregion

					break;
				}
			}
		}

		private static SpreadsheetsService createSpreadsheetsService(string account, string password)
		{
			SpreadsheetsService service = new SpreadsheetsService("WriteBankTransactionRecordsToGoogleSpreadsheet");
			service.setUserCredentials(account,password);
			return service;
		}

		public static bool findRow(List<string[]> rows, string[] row)
		{
			for (int i = rows.Count-1; i >= 0; i--)
			{
				string[] currentRow=rows[i];
				bool match = true;
				for (int j = 0; j<currentRow.Length; j++)
				{
					if (currentRow[j] != row[j])
					{
						match = false;
						break;
					}
				}
				if (match) return true;
			}
			return false;
		}
		public static int getHash(string[] row)
		{
			int hashValue = 0;
			foreach (string c in row)
			{
				hashValue ^= c.GetHashCode(); 
			}
			return hashValue;
		}
		public static string toWestDate(string date)
		{
			string[]items=date.Split('/');
			return string.Format("{0}/{1}/{2}",Int32.Parse(items[0])+1911,items[1],items[2]);
		}
	}
}
